package com.code.apollo.core;

import com.code.apollo.pojo.Configs;
import com.code.apollo.utils.FileUtil;
import freemarker.cache.FileTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <Description>
 * 模板引擎配置类
 * @author Jun Lee
 * @version 1.0
 * @createDate 2020/03/16 15:06
 * @see com.code.apollo.core
 */
public class FreeMarkerConfiguration {
    private static Configuration configuration;

    static {
        configuration = new Configuration(Configuration.getVersion());
        configuration.setDefaultEncoding("utf-8");
    }

    /**
     * 遍历生成代码
     * @param map
     * @param file
     */
    public static void foreachGenerator(Map map,File file) throws Exception {
        ArrayList<File> arrayList = new ArrayList();
        FileUtil.searchAllFile(file,arrayList);
        for (File template : arrayList) {
            loadTemplate(map,template);
        }
    }

    /**
     * 加载模板
     * @param templateFile
     * @return
     * @throws IOException
     */
    public static void loadTemplate(Map map,File templateFile) throws Exception {
        String templateName = templateFile.getAbsolutePath();
        String resultPath = "";
        Configs configs = (Configs) map.get("configs");
        if (templateName.contains("pom.xml")) {
            resultPath = configs.getProject()+"\\pom.xml";
        }else if(templateName.endsWith("yml")){
            resultPath = configs.getProject()+"\\src\\main\\resources\\application.yml";
        }else if(templateName.contains("Mapper.xml")){
            resultPath = configs.getProject()+"\\src\\main\\resources\\mapper\\${table.className}Mapper.xml";
        }else{
            String subPath = templateName.substring(templateName.indexOf("java")+5);
            resultPath = configs.getProject() + "\\src\\main\\java\\" +
                    Arrays.stream(configs.getPathArr()).collect(Collectors.joining("\\")) +"\\"+ subPath;
        }

        //渲染模板路径
        String realTemplatePath = getStringWriter(map, resultPath);
        //读取模板文件
        configuration.setTemplateLoader(new FileTemplateLoader(new File(templateFile.getParent())));
        String substring = templateName.substring(templateName.lastIndexOf("\\") + 1);
        Template cfgTemplate = configuration.getTemplate(substring);
        //创建目录
        File mkdir = FileUtil.mkdir(map.get("outPath").toString(), realTemplatePath);
        //渲染主模板
        writerTemplate(cfgTemplate,map,mkdir);
    }

    /**
     * 渲染模板路径
     * @param map
     * @param subTemplate
     * @return
     * @throws IOException
     * @throws TemplateException
     */
    private static String getStringWriter(Map map, String subTemplate) throws IOException, TemplateException {
        StringWriter out = new StringWriter();
        Template template = new Template("ts",new StringReader(subTemplate),configuration);
        template.process(map,out);
        out.close();
        return out.toString();
    }

    /**
     * 输出模板
     * @param template 模板
     * @param map 数据模型
     * @param outPath 输出路径
     */
    public static void writerTemplate(Template template, Map map,File outPath) throws Exception {
        FileWriter writer = new FileWriter(outPath);
        template.process(map,writer);
        writer.close();
    }
}
